﻿using Avalonia;
using Avalonia.Media.TextFormatting;
using AvaloniaHex.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MySoftLab.DapFlash.Controls
{
    internal readonly struct SimpleTextSource : ITextSource
    {
        private readonly TextRunProperties _defaultProperties;

        private readonly string _text;

        public SimpleTextSource(string text, TextRunProperties defaultProperties)
        {
            _text = text;
            _defaultProperties = defaultProperties;
        }

        public TextRun GetTextRun(int textSourceIndex)
        {
            if (textSourceIndex >= _text.Length)
            {
                return new TextEndOfParagraph();
            }

            return new TextCharacters(_text, _defaultProperties);
        }
    }

    public class CustomOffsetColumn : OffsetColumn
    {
        public static readonly StyledProperty<ulong> BaseAddressProperty;

        public ulong BaseAddress
        {
            get
            {
                return GetValue(BaseAddressProperty);
            }
            set
            {
                SetValue(BaseAddressProperty, value);
            }
        }

        static CustomOffsetColumn()
        {
            BaseAddressProperty = AvaloniaProperty.Register<CustomOffsetColumn, ulong>("BaseAddress", defaultValue: 0);
            BaseAddressProperty.Changed.AddClassHandler<CustomOffsetColumn, ulong>(OnBaseAddressChanged);
        }

        private static void OnBaseAddressChanged(CustomOffsetColumn column, AvaloniaPropertyChangedEventArgs<ulong> args)
        {
            column.HexView?.InvalidateVisualLines();
        }

        private TextLine? CreateTextLine(string text)
        {
            if (base.HexView == null)
            {
                return null;
            }

            GenericTextRunProperties textRunProperties = GetTextRunProperties();
            return TextFormatter.Current.FormatLine(new SimpleTextSource(text, textRunProperties), 0, double.MaxValue, new GenericTextParagraphProperties(textRunProperties));
        }

        public override TextLine? CreateTextLine(VisualBytesLine line)
        {
            if (base.HexView == null)
            {
                throw new InvalidOperationException();
            }

            ulong byteIndex = BaseAddress + line.Range.Start.ByteIndex;
            string text = (IsUppercase ? $"{byteIndex:X8}:" : $"{byteIndex:x8}:");
            return CreateTextLine(text);
        }
    }
}
